import {
  StyleSheet,
  View,
  TouchableOpacity,
  Animated,
  Dimensions,
} from 'react-native';
import {ObserverText} from './ObserverText';
import React, {
  Dispatch,
  SetStateAction,
  useEffect,
  useRef,
  useState,
} from 'react';
import {observer} from 'mobx-react-lite';
import {useGlobalStore} from '../mobx';
import {mergeStyles} from '../themes';
import {dpw12, dpw16, dpw20, dpw24, dpw4, dpw44, dpw8} from '../constants';
import {ObserverView} from './ObserverView';

const screenWidth = Dimensions.get('window').width;

interface TabsProps {
  titles: any;
  pid?: number;
  onChange?: ((_p: number) => void) | Dispatch<SetStateAction<number>>;
  setData?: (_p?: any) => void;
  navigation?: any;
  style?: Record<string, any>;
  titleboxStyle?: Record<string, any>;
  contentStyle?: Record<string, any>;
  titleboxTheme?: Record<string, any>;
  data?: Record<string, any>;
  goDetail?: Function;
}

export const Line = observer(({offsetLeft}: {offsetLeft: number}) => {
  const {theme} = useGlobalStore();
  const fadeAnim = useRef(new Animated.Value(0)).current;

  useEffect(() => {
    Animated.timing(fadeAnim, {
      toValue: offsetLeft,
      duration: 150,
      useNativeDriver: true,
    }).start();
  }, [offsetLeft]);

  return (
    <Animated.View
      style={[styles.linebox, {transform: [{translateX: fadeAnim}]}]}>
      <View
        style={mergeStyles({
          style: {...styles.line},
          themeStyle: {backgroundColor: 'color_1'},
          theme,
        })}
      />
    </Animated.View>
  );
});

export const Content = ({
  titles,
  idx,
  setData,
  navigation,
  contentStyle,
  data,
  goDetail,
}: any) => {
  const fadeAnim = useRef(new Animated.Value(0)).current;

  useEffect(() => {
    Animated.timing(fadeAnim, {
      toValue: -screenWidth * idx,
      duration: 150,
      useNativeDriver: true,
    }).start();
  }, [idx]);

  return (
    <Animated.View
      style={[
        styles.contentbox,
        contentStyle,
        {width: `${100 * titles.length}%`, transform: [{translateX: fadeAnim}]},
      ]}>
      {Array.isArray(titles)
        ? titles.map((it, i) => (
            <View key={i} style={{flex: 1 / titles.length}}>
              {React.cloneElement(it.children, {
                setData,
                navigation,
                idx: idx + 1,
                index: idx,
                data,
                goDetail,
              })}
            </View>
          ))
        : null}
    </Animated.View>
  );
};

export const TabTitle = (props: TabsProps) => {
  const {pid, onChange, titles, titleboxStyle, titleboxTheme} = props;

  return (
    <ObserverView
      style={{...styles.titles, ...titleboxStyle}}
      themeStyle={titleboxTheme}>
      {Array.isArray(titles)
        ? titles.map((it, i) => (
            <TouchableOpacity
              key={i}
              onPress={() => {
                if (onChange) {
                  onChange(i);
                }
              }}
              style={styles.title}>
              <ObserverText isActive={pid === i} {...it} />
            </TouchableOpacity>
          ))
        : null}
      <Line offsetLeft={titles[pid as number]?.left || 0} />
    </ObserverView>
  );
};

export const Tabs = (props: TabsProps) => {
  const {
    titles,
    pid,
    onChange,
    setData,
    navigation,
    style,
    titleboxStyle,
    titleboxTheme,
    contentStyle,
    data,
    goDetail,
  } = props;
  const [idx, setIdx] = useState(0);

  // 如果外部控制就执行外部的方法
  const curIdx = typeof pid === 'number' ? pid : idx;

  const onPress = (id: number) => {
    if (curIdx !== id) {
      if (onChange) {
        onChange(id);
      } else {
        setIdx(id);
      }
    }
  };

  return (
    <View style={[styles.box, style]}>
      <TabTitle
        pid={curIdx}
        onChange={onPress}
        titles={titles}
        titleboxStyle={titleboxStyle}
        titleboxTheme={titleboxTheme}
      />
      <Content
        titles={titles}
        idx={curIdx}
        setData={setData}
        navigation={navigation}
        contentStyle={contentStyle}
        data={data}
        goDetail={goDetail}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  box: {
    flex: 1,
    overflow: 'hidden',
  },
  titles: {
    flexDirection: 'row',
    position: 'relative',
    alignItems: 'center',
    height: dpw44,
  },
  title: {
    paddingHorizontal: dpw16,
    paddingVertical: dpw8,
  },
  linebox: {
    position: 'absolute',
    bottom: 2,
  },
  line: {
    width: dpw20,
    height: dpw4,
    borderRadius: dpw4,
  },
  contentbox: {
    flex: 1,
    overflow: 'hidden',
    flexDirection: 'row',
  },
});
